package peoplesoftsimulator;

import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * @author 597983
 *
 */
public class Parse1 {

    /**
     * @param xml : The XML String to have it's elements parsed out and stored.
     * @param string : The file location that the formatted XML string is to be
     * written to.
     * @return A hashmap containing elements that have been extracted from XML.
     *
     * This method will take in an XML string, take the elements, put them in an
     * arraylist then map them to a hashmap. The reason we write the XML file is
     * so we can store it in the database, so we have the raw file written to
     * the disc in case we need to examine it. This method is a SAXParser, which
     * is available for usage under the Free an Open Source software license.
     */
    public static HashMap<String, Object> parseXML(String xml, String string) {

        //The employee HashMap to be returned once the parser has ran
        final HashMap<String, Object> Employee = new HashMap<String, Object>();

        try {
            /**
             * The SAXParserFactory defines the configuration and API for the
             * SAX Parser. The SAXParser actually created a wrapper for the
             * java.XMLReader, giving it enhanced functionality.
             */
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            //The default class that handles events detected by the SAX parser
            DefaultHandler handler = new DefaultHandler() {

                /**
                 * Each one of these variables actually is meant for two things.
                 * First, there is a boolean value that is set to true anytime
                 * the tag is detected. The second is an ArrayList that we store
                 * these variables in. Together, they form the handling for each
                 * one of the specific datatypes.
                 *
                 * BIRTHDATE = The birthdate of the employee POSTAL = The
                 * postalcode of the employee STATE = The state that the
                 * employee lives in (province, in our case.) COUNTRY = The
                 * country that the employee lives in ADDRESS1 = The primary
                 * address that the employee lives at FIRSTNAME = The employees
                 * first name LASTNAME = The employees last name EMPLID = The
                 * employees ID PHONE = The employees phone number EMAIL_ADDR =
                 * The employees Email Address
                 *
                 * Audit Action is a different tag. This tag represents what
                 * should happen to the information within the XML. If multiple
                 * changes occur in a single XML, then the ArrayLists line up to
                 * reflect their particular Audit Action tag.
                 *
                 * AUDIT_ACTN
                 */
                boolean BIRTHDATE = false;
                ArrayList<String> BIRTHDAY_TYPE = new ArrayList<String>();
                boolean POSTAL = false;
                ArrayList<String> POSTAL_TYPE = new ArrayList<String>();
                boolean STATE = false;
                ArrayList<String> STATE_TYPE = new ArrayList<String>();
                boolean COUNTRY = false;
                ArrayList<String> COUNTRY_TYPE = new ArrayList<String>();
                boolean ADDRESS1 = false;
                ArrayList<String> ADDRESS1_TYPE = new ArrayList<String>();
                boolean FIRSTNAME = false;
                ArrayList<String> FIRSTNAME_TYPE = new ArrayList<String>();
                boolean LASTNAME = false;
                ArrayList<String> LASTNAME_TYPE = new ArrayList<String>();
                boolean EMPLID = false;
                ArrayList<String> EMPLID_TYPE = new ArrayList<String>();
                boolean PHONE = false;
                ArrayList<String> PHONE_TYPE = new ArrayList<String>();
                boolean EMAIL_ADDR = false;
                ArrayList<String> EMAIL_ADDR_TYPE = new ArrayList<String>();
                boolean AUDIT_ACTN = false;
                ArrayList<String> AUDIT_TYPE = new ArrayList<String>();

                /* (non-Javadoc)
                 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
                 */
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

                    //System.out.println("Start Element :" + qName);

                    //This if chain checks each tag that is processed. If the name matches the String, then the boolean flag is tripped to identify the item.
                    if (qName.equalsIgnoreCase("AUDIT_ACTN")) {
                        AUDIT_ACTN = true;
                    }
                    if (qName.equalsIgnoreCase("BIRTHDATE")) {
                        BIRTHDATE = true;
                    }
                    if (qName.equalsIgnoreCase("POSTAL")) {
                        POSTAL = true;
                    }
                    if (qName.equalsIgnoreCase("STATE")) {
                        STATE = true;
                    }
                    if (qName.equalsIgnoreCase("COUNTRY")) {
                        COUNTRY = true;
                    }
                    if (qName.equalsIgnoreCase("ADDRESS1")) {
                        ADDRESS1 = true;
                    }
                    if (qName.equalsIgnoreCase("FIRSTNAME")) {
                        FIRSTNAME = true;
                    }
                    if (qName.equalsIgnoreCase("LASTNAME")) {
                        LASTNAME = true;
                    }
                    if (qName.equalsIgnoreCase("EMPLID")) {
                        EMPLID = true;
                    }
                    if (qName.equalsIgnoreCase("PHONE")) {
                        PHONE = true;
                    }
                    if (qName.equalsIgnoreCase("EMAIL_ADDRESS")) {
                        EMAIL_ADDR = true;
                    }

                }

                /* (non-Javadoc)
                 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
                 */
                public void endElement(String uri, String localName, String qName) throws SAXException {

                    //System.out.println("End Element :" + qName);

                }

                /* (non-Javadoc)
                 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
                 */
                public void characters(char ch[], int start, int length) throws SAXException {
                    /**
                     * The concept of this method is fairly straightforward. We
                     * create a string from the element found between the two
                     * tags. From there, we check to make sure this take isn't a
                     * blank, null or a newline character. If the character is
                     * good, then the boolean flag is reset and the resulting
                     * string is added to it's appropriate ArrayList. The
                     * process is the same for every step, so understanding one
                     * allows you to understand all of them.
                     */
                    if (AUDIT_ACTN) {
                        String Audit_Actn = new String(ch, start, length);
                        if (Audit_Actn.equals(" ") || Audit_Actn.equals("") || Audit_Actn == null || Audit_Actn.equals("\n")) {
                            AUDIT_ACTN = false;
                        } else {
                            AUDIT_TYPE.add(Audit_Actn);
                            AUDIT_ACTN = false;
                            Employee.put("AUDIT_ACTN", AUDIT_TYPE);
                        }
                    }
                    if (EMPLID) {
                        String EmplId = new String(ch, start, length);
                        if (EmplId.equals(" ") || EmplId.equals("") || EmplId == null || EmplId.equals("\n")) {
                            EMPLID = false;
                        } else {
                            EMPLID_TYPE.add(EmplId);
                            EMPLID = false;
                            Employee.put("EMPLID", EMPLID_TYPE);
                        }
                    }
                    if (BIRTHDATE) {
                        String birthday = new String(ch, start, length);
                        if (birthday.equals(" ") || birthday.equals("") || birthday == null || birthday.equals("\n")) {
                            BIRTHDATE = false;
                        } else {
                            BIRTHDAY_TYPE.add(birthday);
                            BIRTHDATE = false;
                            Employee.put("BIRTHDAY", BIRTHDAY_TYPE);
                        }
                    }
                    if (POSTAL) {
                        String postal = new String(ch, start, length);
                        if (postal.equals(" ") || postal.equals("") || postal == null || postal.equals("\n")) {
                            POSTAL = false;
                        } else {
                            POSTAL_TYPE.add(postal);
                            POSTAL = false;
                            Employee.put("POSTAL", POSTAL_TYPE);
                        }
                    }

                    if (STATE) {
                        String state = new String(ch, start, length);
                        if (state.equals(" ") || state.equals("") || state == null || state.equals("\n")) {
                            STATE = false;
                        } else {
                            STATE_TYPE.add(state);
                            STATE = false;
                            Employee.put("STATE", STATE_TYPE);
                        }

                    }

                    if (COUNTRY) {
                        String country = new String(ch, start, length);
                        if (country.equals(" ") || country.equals("") || country == null || country.equals("\n")) {
                            COUNTRY = false;
                        } else {
                            COUNTRY_TYPE.add(country);
                            COUNTRY = false;
                            Employee.put("COUNTRY", COUNTRY_TYPE);
                        }

                    }
                    if (ADDRESS1) {
                        String address = new String(ch, start, length);
                        if (address.equals(" ") || address.equals("") || address == null || address.equals("\n")) {
                            ADDRESS1 = false;
                        } else {
                            ADDRESS1_TYPE.add(address);
                            ADDRESS1 = false;
                            Employee.put("ADDRESS", ADDRESS1_TYPE);
                        }

                    }
                    if (FIRSTNAME) {
                        String firstName = new String(ch, start, length);
                        if (firstName.equals(" ") || firstName.equals("") || firstName == null || firstName.equals("\n")) {
                            FIRSTNAME = false;
                        } else {
                            FIRSTNAME_TYPE.add(firstName);
                            FIRSTNAME = false;
                            Employee.put("FIRSTNAME", FIRSTNAME_TYPE);
                        }

                    }
                    if (LASTNAME) {
                        String lastName = new String(ch, start, length);
                        if (lastName.equals(" ") || lastName.equals("") || lastName == null || lastName.equals("\n")) {
                            LASTNAME = false;
                        } else {
                            LASTNAME_TYPE.add(lastName);
                            LASTNAME = false;
                            Employee.put("LASTNAME", LASTNAME_TYPE);
                        }
                    }
                    if (PHONE) {
                        String phone = new String(ch, start, length);
                        if (phone.equals(" ") || phone.equals("") || phone == null || phone.equals("\n")) {
                            PHONE = false;
                        } else {
                            PHONE_TYPE.add(phone);
                            PHONE = false;
                            Employee.put("PHONE", PHONE_TYPE);
                        }

                    }
                    if (EMAIL_ADDR) {
                        String email = new String(ch, start, length);
                        if (email.equals(" ") || email.equals("") || email == null || email.equals("\n")) {
                            EMAIL_ADDR = false;
                        } else {
                            EMAIL_ADDR_TYPE.add(email);
                            EMAIL_ADDR = false;
                            Employee.put("EMAIL", EMAIL_ADDR_TYPE);
                        }

                    }
                }

            };
            // End of handler method
            /**
             * Now that all the above handler parameters have been identified,
             * we do some tricky stuff. The XmlReader.stringToDom method will
             * take in an XML string, and return the created XML file to a
             * specified location in the driver. Once the XML file is created,
             * the saxParser.parse method will read in the file and uses the
             * defined handler as the rules for parsing.
             */
            XmlReader.stringToDom(xml, string);
            saxParser.parse(string, handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //returns the employee HashMap
        return Employee;
    }
}
